package protocol

import (
	"fmt"
	"mytest/week9/pkg/bufio"
	"mytest/week9/pkg/bytes"
	"mytest/week9/pkg/encoding/binary"
)

const (
	_pkgSize       = 4
	_headerSize    = 2
	_verSize       = 2
	_opSize        = 4
	_seqSize       = 4
	_rowHeaderSize = _pkgSize + _headerSize + _verSize + _opSize + _seqSize

	_headerOffset = _pkgSize
	_verOffset    = _headerOffset + _headerSize
	_opOffset     = _verOffset + _verSize
	_seqOffset    = _opOffset + _opSize
)

type Proto struct {
	Body []byte
	Op   int32
	Ver  int16
	Seq  int32
}

func (p *Proto) WriteTo(b *bytes.Writer) error {
	var (
		pkgLen = int32(len(p.Body)) + _rowHeaderSize
		buf    []byte
	)
	buf = b.Peek(_rowHeaderSize)
	// 整个包的长度
	binary.BigEndian.PutInt32(buf, pkgLen)

	// 整个header的长度
	binary.BigEndian.PutInt16(buf[_headerOffset:], int16(_rowHeaderSize))
	//DataToBytes(buf[_headerOffset:], int16(_rowHeaderSize))

	// 版本
	binary.BigEndian.PutInt16(buf[_verOffset:], p.Ver)
	//DataToBytes(buf[_verOffset:], p.Ver)

	// 操作的长度
	binary.BigEndian.PutInt32(buf[_opOffset:], p.Op)
	// seq
	binary.BigEndian.PutInt32(buf[_seqOffset:], p.Seq)
	if p.Body != nil {
		b.Write(p.Body[:])
		//buf = append(buf, p.Body[:]...)
	}
	//fmt.Println(buf)
	return nil
}

func (p *Proto) ReadTCP(rr *bufio.Reader) error {
	var (
		buf  []byte
		body []byte
		err  error
	)

	//buf = make([]byte, _rowHeaderSize)
	buf, err = rr.Pop(_rowHeaderSize)
	//_, _ = rr.Read(buf)
	//_, err = io.ReadFull(rr, buf)
	//fmt.Println(buf)
	// 整个包的长度
	packLen := int(binary.BigEndian.Int32(buf[:_headerOffset]))
	// 整个header的长度
	headerLength := int(binary.BigEndian.Int16(buf[_headerOffset:_verOffset]))
	// 版本
	p.Ver = binary.BigEndian.Int16(buf[_verOffset:_opOffset])
	// 操作
	p.Op = binary.BigEndian.Int32(buf[_opOffset:_seqOffset])
	// 编号
	p.Seq = binary.BigEndian.Int32(buf[_seqOffset:])
	bodyLen := packLen - headerLength
	fmt.Println(bodyLen)
	body, err = rr.Pop(bodyLen)
	p.Body = body
	fmt.Printf("%+v\n", p)
	return err
}
